﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Police.Configuration;
using Police.Svn;
using System.IO;

namespace Police
{
    /// <summary>
    /// Work pre-commit informations and check if operation can be committed to repository server.
    /// </summary>
    public sealed class PreCommitValidator : IPreCommitValidator
    {
        private Settings _settings;
        private ISvnRepository _svnRepository;
        private IPreCommitRulesProvider _rulesProvider;
        private IEnumerable<IPreCommitRule> _preCommitRules;

        /// <summary>
        /// Initialize new pre commit validator with default configuration.
        /// </summary>
        /// <remarks>Settings are loaded using Configuration.xml file, this file must be presente
        /// in root directory of Police application.</remarks>
        public PreCommitValidator()
            : this(Settings.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration.xml")), new SvnRepository(), new PreCommitRulesProvider())
        {

        }

        /// <summary>
        /// Initialize new pre commit validator with custom settings and validator.
        /// </summary>
        /// <param name="settings">Settings to use for pre-commit validation</param>
        /// <param name="svnRepository">SVN repository to use for data retrieve.</param>
        public PreCommitValidator(Settings settings, ISvnRepository svnRepository, IPreCommitRulesProvider rulesProvider)
        {
            _settings = settings;
            _svnRepository = svnRepository;
            _rulesProvider = rulesProvider;
            _preCommitRules = rulesProvider.LoadValidationRules();
        }

        /// <summary>
        /// Work informations relatives to specific transaction id and repository path.
        /// </summary>
        /// <param name="transactionId">SVN pre-commit transaction</param>
        /// <param name="repositoryPath">SVN repository path</param>
        public PreCommitValidationResponse Work(String transactionId, String repositoryPath)
        {
            PreCommitValidationResponse preCommitResponse = new PreCommitValidationResponse();
            ISvnChangeInfo svnChangeInfo = _svnRepository.GetSvnRevisionInfo(transactionId, repositoryPath);

            foreach (IPreCommitRule rule in _preCommitRules)
            {
                try 
                {
                    rule.Validate(_settings, svnChangeInfo);
                }
                catch (PreCommitRuleException ex)
                {
                    preCommitResponse.Errors.Add(ex.Message);
                    break;
                }
            }

            return preCommitResponse;
        }


    }
}
